#include "EnumMapping.h"

using namespace BroodWar;
using namespace BroodWar::Api;
using namespace BroodWar::Api::Enum;
using namespace BroodWar::Addon;

namespace BroodWar
{
	template <typename T>
	char* get_c_str(T t)
	{
		return (char*)t.c_str();
	}

	template <typename T>
	char* get_c_str_from_name(T t)
	{
		return (char*)t.getName().c_str();
	}

	static EnumMapping::EnumMapping()
	{
		UnitCommandType = gcnew EnumMap<BWAPI::UnitCommandType, Api::Enum::UnitCommandType>(
			45,
			&BWAPI::UnitCommandTypes::allUnitCommandTypes,
			&BWAPI::UnitCommandTypes::getUnitCommandType,
			(char*(*)(BWAPI::UnitCommandType))(&get_c_str<BWAPI::UnitCommandType>));
		
		DamageType = gcnew EnumMap<BWAPI::DamageType, Api::Enum::DamageType>(
			7,
			&BWAPI::DamageTypes::allDamageTypes,
			&BWAPI::DamageTypes::getDamageType,
			(char*(*)(BWAPI::DamageType))(&get_c_str<BWAPI::DamageType>));
		
		BulletType = gcnew EnumMap<BWAPI::BulletType, Api::Enum::BulletType>(
			37,
			&BWAPI::BulletTypes::allBulletTypes,
			&BWAPI::BulletTypes::getBulletType,
			(char*(*)(BWAPI::BulletType))(&get_c_str<BWAPI::BulletType>));
		
		ExplosionType = gcnew EnumMap<BWAPI::ExplosionType, Api::Enum::ExplosionType>(
			25,
			&BWAPI::ExplosionTypes::allExplosionTypes,
			&BWAPI::ExplosionTypes::getExplosionType,
			(char*(*)(BWAPI::ExplosionType))(&get_c_str<BWAPI::ExplosionType>));
		
		GameType = gcnew EnumMap<BWAPI::GameType, Api::Enum::GameType>(
			16,
			&BWAPI::GameTypes::allGameTypes,
			&BWAPI::GameTypes::getGameType,
			(char*(*)(BWAPI::GameType))(&get_c_str<BWAPI::GameType>));
		
		PlayerType = gcnew EnumMap<BWAPI::PlayerType, Api::Enum::PlayerType>(
			11,
			&BWAPI::PlayerTypes::allPlayerTypes,
			&BWAPI::PlayerTypes::getPlayerType,
			(char*(*)(BWAPI::PlayerType))(&get_c_str<BWAPI::PlayerType>));
		
		UnitSizeType = gcnew EnumMap<BWAPI::UnitSizeType, Api::Enum::UnitSizeType>(
			6,
			&BWAPI::UnitSizeTypes::allUnitSizeTypes,
			&BWAPI::UnitSizeTypes::getUnitSizeType,
			(char*(*)(BWAPI::UnitSizeType))(&get_c_str<BWAPI::UnitSizeType>));
		
		OrderType = gcnew EnumMap<BWAPI::Order, Api::Enum::OrderType>(
			157,
			&BWAPI::Orders::allOrders,
			&BWAPI::Orders::getOrder,
			(char*(*)(BWAPI::Order))(&get_c_str<BWAPI::Order>));
		
		ErrorType = gcnew EnumMap<BWAPI::Error, Api::Enum::ErrorType>(
			28,
			&BWAPI::Errors::allErrors,
			&BWAPI::Errors::getError,
			(char*(*)(BWAPI::Error))(&get_c_str<BWAPI::Error>));
		
		RaceType = gcnew EnumMap<BWAPI::Race, Api::Enum::RaceType>(
			7,
			&BWAPI::Races::allRaces,
			&BWAPI::Races::getRace,
			(char*(*)(BWAPI::Race))(&get_c_str<BWAPI::Race>));
		
		UnitType = gcnew EnumMap<BWAPI::UnitType, Api::Enum::UnitType>(
			211,
			&BWAPI::UnitTypes::allUnitTypes,
			&BWAPI::UnitTypes::getUnitType,
			(char*(*)(BWAPI::UnitType))(&get_c_str<BWAPI::UnitType>));
		
		TechType = gcnew EnumMap<BWAPI::TechType, Api::Enum::TechType>(
			36,
			&BWAPI::TechTypes::allTechTypes,
			&BWAPI::TechTypes::getTechType,
			(char*(*)(BWAPI::TechType))(&get_c_str<BWAPI::TechType>));
		
		UpgradeType = gcnew EnumMap<BWAPI::UpgradeType, Api::Enum::UpgradeType>(
			52,
			&BWAPI::UpgradeTypes::allUpgradeTypes,
			&BWAPI::UpgradeTypes::getUpgradeType,
			(char*(*)(BWAPI::UpgradeType))(&get_c_str<BWAPI::UpgradeType>));
		
		WeaponType = gcnew EnumMap<BWAPI::WeaponType, Api::Enum::WeaponType>(
			102,
			&BWAPI::WeaponTypes::allWeaponTypes,
			&BWAPI::WeaponTypes::getWeaponType,
			(char*(*)(BWAPI::WeaponType))(&get_c_str<BWAPI::WeaponType>));

		BuildType = gcnew EnumMap<BWSAL::BuildType, Addon::BuildType>(
			203,
			static_cast<std::set<BWSAL::BuildType> &(*)()>(&BWSAL::BuildTypes::allBuildTypes),
			&BWSAL::BuildTypes::getBuildType,
			(char*(*)(BWSAL::BuildType))(&get_c_str_from_name<BWSAL::BuildType>));

		TaskStateType = gcnew EnumMap<BWSAL::TaskState, Addon::TaskStateType>(
			9,
			&BWSAL::TaskStates::allTaskStates,
			&BWSAL::TaskStates::getTaskState,
			(char*(*)(BWSAL::TaskState))(&get_c_str_from_name<BWSAL::TaskState>));
	}

	System::Drawing::Color EnumMapping::ToNativeColor(BWAPI::Color color)
	{
		return System::Drawing::Color::FromArgb(color.red(), color.green(), color.blue());
	}

	System::Drawing::Color EnumMapping::ToNativeColor(BWAPI::Color *color)
	{
		return System::Drawing::Color::FromArgb(color->red(), color->green(), color->blue());
	}

	BWAPI::Color* EnumMapping::ToBwColorPointer(System::Drawing::Color^ color)
	{
		return new BWAPI::Color(color->R, color->G, color->B);
	}

	BWAPI::Color EnumMapping::ToBwColor(System::Drawing::Color^ color)
	{
		BWAPI::Color clr(color->R, color->G, color->B);
		return clr;
	}
}